package com.zwl.android.aidoctor;

import android.app.Activity;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.usb.UsbConstants;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbEndpoint;

import androidx.appcompat.app.AppCompatActivity;

import android.hardware.usb.UsbInterface;
import android.hardware.usb.UsbManager;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.provider.ContactsContract;
import android.util.Log;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.zwl.android.aidoctor.tcm.MaiXiangDsc;
import com.zwl.android.aidoctor.util.JSONUtil;
import com.zwl.android.aidoctor.util.MD5;
import com.zwl.android.aidoctor.util.MapSortUtil;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import okhttp3.Call;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

/**
 * @author tcmaiok.org
 * 脉象仪数据采集处理
 */
public class DataActivity extends AppCompatActivity {
    public static final String ACTION_USB_PERMISSION = "com.zwl.USB_PERMISSION";
    private PendingIntent mPermissionIntent;
    private List<String> dataLs = new ArrayList<String>();//采集的脉象数据
    private String[] dataListMX = MaiXiangDsc.mxArr;
    private UsbManager usbManager;
    private UsbEndpoint usbOut, usbIn;
    private Button button_start;
    private UsbDeviceConnection usbConnection;
    private TextView textView_mx;//脉象处理提示
    private ListView listView_end_dsc;
    private RealChart realChart;
    private int isStartCai = 0;//是否开始采集
    ////脉象仪接口地址请联系：深圳睿蜂网科技有限公司
    //https://m.1688.com/offer/608871951954.html
    private String mxApiRootUrl = "http://ip:port/mx";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_data);
        registerReceiver(DataActivity.this);
        initView();
        //save();
        Real();
        if (MainActivity.usbDevice != null) {
            requestPermission(MainActivity.usbDevice);
        } else {
            Toast.makeText(DataActivity.this, "usb设备错误", Toast.LENGTH_SHORT).show();
        }

        if (getDeviceList().size() > 0) {
            if (hasPermission(getDeviceList().get(0))) {
                openPort(getDeviceList().get(0));
            } else {
                requestPermission(getDeviceList().get(0));
            }
        }
    }

    public List<UsbDevice> getDeviceList() {
        HashMap<String, UsbDevice> deviceList = usbManager.getDeviceList();
        Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
        List<UsbDevice> usbDevices = new ArrayList<>();
        while (deviceIterator.hasNext()) {
            UsbDevice device = deviceIterator.next();
            usbDevices.add(device);
            Log.e("USBUtil", "getDeviceList: " + device.getDeviceName());
        }
        return usbDevices;
    }

    private void initView() {
        usbManager = (UsbManager) getSystemService(Context.USB_SERVICE);

        textView_mx = findViewById(R.id.textView_mx);
        listView_end_dsc = findViewById(R.id.end_dsc_view);
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(
                DataActivity.this,android.R.layout.simple_list_item_1,dataListMX);
        listView_end_dsc.setAdapter(adapter);
        button_start = findViewById(R.id.button_start);
        button_start.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //byte[] bytes =  hexStrToByteArray(editText.getText().toString());
                //usbConnection.bulkTransfer(usbOut, bytes, bytes.length, 500);

                dataLs = new ArrayList<String>();
                isStartCai = 1;//开始
                button_start.setEnabled(false);
                textView_mx.setText("请稍候，数据采集中...");
                textView_mx.invalidate();
            }
        });
    }


    /**
     * 判断对应 USB 设备是否有权限
     */
    public boolean hasPermission(UsbDevice device) {
        return usbManager.hasPermission(device);
    }

    /**
     * 请求获取指定 USB 设备的权限
     */
    public void requestPermission(UsbDevice device) {
        if (device != null) {
            if (usbManager.hasPermission(device)) {
                Toast.makeText(this, "已经获取到权限", Toast.LENGTH_SHORT).show();
            } else {
                if (mPermissionIntent != null) {
                    usbManager.requestPermission(device, mPermissionIntent);
                    Toast.makeText(this, "请求USB权限", Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(this, "请注册USB广播", Toast.LENGTH_LONG).show();
                }
            }
        }
    }

    public void registerReceiver(Activity context) {
        mPermissionIntent = PendingIntent.getBroadcast(context, 0, new Intent(ACTION_USB_PERMISSION), 0);
        IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
        filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
        filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
        context.registerReceiver(mUsbReceiver, filter);
    }

    private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            //tvInfo.append("BroadcastReceiver in\n");
            UsbDevice device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
            if (ACTION_USB_PERMISSION.equals(action)) {
                synchronized (this) {
                    if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
                        if (device != null) {
                            // tvInfo.append("usb EXTRA_PERMISSION_GRANTED");
                            Toast.makeText(DataActivity.this, "授权成功！", Toast.LENGTH_SHORT).show();
                            openPort(MainActivity.usbDevice);
                        }
                    } else {
                        Toast.makeText(DataActivity.this, "授权失败！", Toast.LENGTH_SHORT).show();
                        requestPermission(device);
                        //tvInfo.append("usb EXTRA_PERMISSION_GRANTED null!!!");
                    }
                }
            } else if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action)) {
                // 有新的设备插入了，在这里一般会判断这个设备是不是我们想要的，是的话就去请求权限
                if (hasPermission(device)) {
                    openPort(device);
                } else {
                    requestPermission(device);
                }
            } else if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {
                // 有设备拔出了
                mHandlerUsbUI.removeCallbacks(runnable);// 关闭定时器处理
                if (usbConnection != null)
                    usbConnection.releaseInterface(usbInterface);
                usbConnection.close();
            }
        }
    };
    UsbInterface usbInterface;

    public boolean openPort(UsbDevice device) {
        //获取设备接口，一般只有一个
        usbInterface = device.getInterface(0);
        Toast.makeText(DataActivity.this, "接口数量" + device.getInterfaceCount(), Toast.LENGTH_SHORT).show();

        // 判断是否有权限
        if (hasPermission(device)) {
            // 打开设备，获取 UsbDeviceConnection 对象，连接设备，用于后面的通讯
            usbConnection = usbManager.openDevice(device);

            if (usbConnection == null) {
                return false;
            }
            if (usbConnection.claimInterface(usbInterface, true)) {
                Toast.makeText(DataActivity.this, "找到 USB 设备接口", Toast.LENGTH_SHORT).show();
            } else {
                usbConnection.close();
                Toast.makeText(DataActivity.this, "没有找到 USB 设备接口", Toast.LENGTH_SHORT).show();
                return false;
            }
        } else {
            Toast.makeText(DataActivity.this, "没有 USB 权限", Toast.LENGTH_SHORT).show();
            return false;
        }

        //获取接口上的两个端点，分别对应 OUT 和 IN
        for (int i = 0; i < usbInterface.getEndpointCount(); ++i) {
            UsbEndpoint end = usbInterface.getEndpoint(i);
            if (end.getDirection() == UsbConstants.USB_DIR_IN) {
                usbIn = end;
                mHandlerUsbUI.postDelayed(runnable, 50);// 打开定时器，50ms后执行runnable操作
            } else {
                usbOut = end;
            }
        }
        return true;
    }

    public void Real() {
        realChart = (RealChart) findViewById(R.id.real_view);
    }

    private FileOutputStream fos;

    private void save() {
        try {
            File sdCardDir = Environment.getExternalStorageDirectory();
            File saveFile = new File(sdCardDir, "abc.txt");
            fos = new FileOutputStream(saveFile, true);

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

    // 从设备接收数据bulkIn
    private void receiveMessageFromPoint() {
        byte[] buffer = new byte[1];

        if (usbConnection.bulkTransfer(usbIn, buffer, buffer.length, 20) > 0) {
            realChart.addPointToList(buffer[0] & 0xff);
            if (isStartCai == 0) {//停止采集
                return;
            }
            if (dataLs.size() > 800) {
                isStartCai = 0;//停止采集
                webApiMx();//脉象分析
            }
            if (isStartCai == 1) {//启用采集
                String di = String.valueOf(buffer[0] & 0xff);//字节二进制转十进制
                dataLs.add(di);
            }
            Log.i("收到", (buffer[0] & 0xff) + "");
        }

    }

    public static byte[] hexStrToByteArray(String str) {
        if (str == null) {
            return null;
        }
        if (str.length() == 0) {
            return new byte[0];
        }
        byte[] byteArray = new byte[str.length() / 2];
        for (int i = 0; i < byteArray.length; i++) {
            String subStr = str.substring(2 * i, 2 * i + 2);
            byteArray[i] = ((byte) Integer.parseInt(subStr, 16));
        }
        return byteArray;
    }

    public static String bytesToHexString(byte[] src) {
        StringBuilder stringBuilder = new StringBuilder("");
        if (src == null || src.length <= 0) {
            return null;
        }
        for (int i = 0; i < src.length; i++) {
            int v = src[i] & 0xFF;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv);
        }
        return stringBuilder.toString();
    }

    Handler mHandlerUsbUI = new Handler();
    Runnable runnable = new Runnable() {
        @Override
        public void run() {
            receiveMessageFromPoint();
            mHandlerUsbUI.postDelayed(this, 10);// 10ms后执行this，即runable
        }
    };

    Handler mHandlerUI = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            String txt = (String) msg.obj;
            if (txt.equals("setButtonEnabled")) {
                button_start.setEnabled(true);
            } else {
                textView_mx.setText(txt);
                textView_mx.invalidate();
            }
        }
    };
    Handler mHandlerEndDscUI = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            String[] txt = (String[]) msg.obj;
            dataListMX = txt;

        }
    };

    private void webApiMx() {//通过webapi判断脉象
        try {
            textView_mx.setText("请稍候，数据分析中...");
            textView_mx.invalidate();

            String mxApiUrl = mxApiRootUrl;
            String mxData = "";
            for (int i = 0; i < 700; i++) {
                mxData = mxData + " " + dataLs.get(i);
            }
            mxData = mxData.trim();
            String md5Str = mxData + "100jqseckey";
            md5Str = MD5.getMD5Str(md5Str);
            mxApiUrl = mxApiUrl + "?md5=" + md5Str + "&data=" + mxData;

            OkHttpClient okClient = new OkHttpClient();
            Request.Builder builder = new Request.Builder();
            builder.url(mxApiUrl);
            Request request = builder.build();
            final Call call = okClient.newCall(request);
            new Thread(new Runnable() {
                @Override
                public void run() {//必须异步
                    webApiMxHandle(call);
                }
            }).start();

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    private void webApiMxHandle(Call call) {
        try {
            Response response = call.execute();
            String result = response.body().string().trim();

            Map retMap = JSONUtil.json2Map(result);
            if (String.valueOf(retMap.get("errcode")).equals("0")) {
                HashMap<String, Double> dataMap = new HashMap<>();//循环转换
                for (Object key : retMap.keySet()) {
                    if (String.valueOf(key).endsWith("脉")) {
                        dataMap.put(String.valueOf(key), Double.valueOf(String.valueOf(retMap.get(key))));
                    }
                }
                //---dataMap排序----
                HashMap<String, Double> mapCs_Sorted = MapSortUtil.sortByValue(dataMap);
                int i = 0;
                String selMx = "结论：";
                List<String> mxSelList = new ArrayList();
                for (String key : mapCs_Sorted.keySet()) {
                    String mxOne = key + ":" + mapCs_Sorted.get(key);
                    for (String keyMX : MaiXiangDsc.mxMap.keySet()) {
                        if (key.contains(keyMX)){
                            mxSelList.add(keyMX+"脉："+ MaiXiangDsc.mxMap.get(keyMX));
                        }
                    }
                    //System.out.println(key + ":" + mapCs_Sorted.get(key));
                    if (i == 2) {//取最相似的2个脉象
                        break;
                    }
                    selMx = selMx + mxOne + "%;";
                    i++;
                }
                selMx = selMx + "脉率:" + String.valueOf(retMap.get("脉率")) + "次/分。";
                //------------------------------------------
                Message msg2 = new Message();
                msg2.obj = selMx;
                mHandlerUI.sendMessage(msg2);
                //-------------------------------------------
                //dataListMX= (String[]) mxSelList.toArray();
                //Message msgListMx = new Message();
                //msgListMx.obj = mxSelList.toArray();
                //mHandlerEndDscUI.sendMessage(msgListMx);
            } else {
                Message msg3 = new Message();
                msg3.obj = "数据不完整，请重新开始！";
                mHandlerUI.sendMessage(msg3);

            }

        } catch (IOException e) {
            e.printStackTrace();
            Message msgErr = new Message();
            msgErr.obj = e.getMessage();
            mHandlerUI.sendMessage(msgErr);
        }

        Message msg = new Message();
        msg.obj = "setButtonEnabled";
        mHandlerUI.sendMessage(msg);
    }

}
